from object.unit import Tactic, Order
from conf.enum import TacticType, OrderDir


# ------------ 2024-12 策略卡包 ------------
# ------------------------------------------ 过滤战法 Filter-------------------------------------------
class ATR1F(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "ATR过滤1"
        self.describe = """若短期atr小于长期atr的0.8，保持仓位并跳过"""
        self.tactic_type = TacticType.FILTER

        self.factor_name = ['atr5', 'atr20']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        atr5 = self.bt_task.atr5
        atr20 = self.bt_task.atr20

        if atr5[self.idx] < atr20[self.idx] * 0.8:
            return Order(None,  "该行情被过掉", OrderDir.PASS)


class ATR2F(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "ATR过滤2"
        self.describe = """若短期atr大于长期atr的1.5，清空仓位并跳过"""
        self.tactic_type = TacticType.FILTER

        self.factor_name = ['atr5', 'atr20']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        atr5 = self.bt_task.atr5
        atr20 = self.bt_task.atr20

        if atr5[self.idx] > atr20[self.idx] * 1.5:
            return Order(0, "该行情被拒绝", OrderDir.REJECT)


class STD1F(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "标准差过滤1"
        self.describe = """若短期std小于长期std的0.8，保持仓位并跳过"""
        self.tactic_type = TacticType.FILTER

        self.factor_name = ['std5', 'std20']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        std5 = self.bt_task.std5
        std20 = self.bt_task.std20

        if std5[self.idx] < std20[self.idx] * 0.8:
            return Order(None,  "该行情被过掉", OrderDir.PASS)


class STD2F(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "标准差过滤2"
        self.describe = """若短期std大于长期std的1.5，清空仓位并跳过"""
        self.tactic_type = TacticType.FILTER

        self.factor_name = ['std5', 'std20']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        std5 = self.bt_task.std5
        std20 = self.bt_task.std20

        if std5[self.idx] > std20[self.idx] * 1.5:
            return Order(0, "该行情被拒绝", OrderDir.REJECT)


class ADX1F(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "ADX过滤1"
        self.describe = """若当前ADX小于25，清空仓位并跳过"""
        self.tactic_type = TacticType.FILTER

        self.factor_name = ['adx']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        adx = self.bt_task.adx
        if adx[self.idx] < 25:
            return Order(0, "该行情被拒绝", OrderDir.PASS)


class ADX2F(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "ADX过滤2"
        self.describe = """若当前ADX小于50，保持仓位并跳过"""
        self.tactic_type = TacticType.FILTER

        self.factor_name = ['adx']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        adx = self.bt_task.adx
        if adx[self.idx] < 50:
            return Order(None, "该行情被过掉", OrderDir.PASS)


class DILF(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "DI过滤-多"
        self.describe = """若当前为上涨趋势或震荡，保持仓位并跳过"""
        self.tactic_type = TacticType.FILTER

        self.factor_name = ['plus_di', 'minus_di']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        plus_di = self.bt_task.plus_di
        minus_di = self.bt_task.minus_di
        if plus_di[self.idx] > minus_di[self.idx] * 0.8:
            return Order(None, "该行情被过掉", OrderDir.PASS)


class DISF(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "DI过滤-空"
        self.describe = """若当前为下跌趋势或震荡，保持仓位并跳过"""
        self.tactic_type = TacticType.FILTER

        self.factor_name = ['plus_di', 'minus_di']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        plus_di = self.bt_task.plus_di
        minus_di = self.bt_task.minus_di
        if plus_di[self.idx] < minus_di[self.idx] * 1.2:
            return Order(None, "该行情被过掉", OrderDir.PASS)


# ------------------------------------------ 开仓战法 Open-------------------------------------------


class UpCrossO(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "均线上穿"
        self.describe = """当sma5上穿sma20时，开立订单"""
        self.tactic_type = TacticType.OPEN

        self.factor_name = ['sma5', 'sma20']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        sma5 = self.bt_task.sma5
        sma20 = self.bt_task.sma20
        if sma5[self.idx] > sma20[self.idx] and sma5[-2] <= sma20[-2]:
            return Order(1,  "均线上穿，开立订单")


class DownCrossO(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "均线下穿"
        self.describe = """当sma5下穿sma20时，开立订单"""
        self.tactic_type = TacticType.OPEN

        self.factor_name = ['sma5', 'sma20']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        sma5 = self.bt_task.sma5
        sma20 = self.bt_task.sma20
        if sma5[self.idx] < sma20[self.idx] and sma5[-2] >= sma20[-2]:
            return Order(1, "均线下穿，开立订单")


class CrossUpperBandO(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "上穿boll带"
        self.describe = """当close上穿boll时，开立订单"""
        self.tactic_type = TacticType.OPEN

        self.factor_name = ['mean', 'std']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        close = self.bt_task.close
        mean = self.bt_task.mean
        std = self.bt_task.std
        if close[self.idx] > mean[self.idx] + 2 * std[self.idx] and close[-2] <= mean[-2] + 2 * std[-2]:
            return Order(1, "上穿boll带，开立订单")


class CrossLowerBandO(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "下穿boll带"
        self.describe = """当close下穿boll时，开立订单"""
        self.tactic_type = TacticType.OPEN

        self.factor_name = ['mean', 'std']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        close = self.bt_task.close
        mean = self.bt_task.mean
        std = self.bt_task.std
        if close[self.idx] < mean[self.idx] - 2 * std[self.idx] and close[-2] >= mean[-2] - 2 * std[-2]:
            return Order(1, "下穿boll带，开立订单")

# ------------------------------------------ 平仓战法 Close-------------------------------------------


class WaveEnlargeC(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "波动放大"
        self.describe = """当atr明显大于5K前，平掉订单"""
        self.tactic_type = TacticType.CLOSE

        self.factor_name = ['atr_rate']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        atr_rate = self.bt_task.atr_rate
        if atr_rate[self.idx] > atr_rate[self.idx-5] * 1.5:
            return Order(1, "波动放大，平掉订单")


class WaveReduceC(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "波动缩小"
        self.describe = """当atr明显小于5K前，平掉订单"""
        self.tactic_type = TacticType.CLOSE

        self.factor_name = ['atr_rate']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        atr_rate = self.bt_task.atr_rate
        if atr_rate[self.idx] < atr_rate[self.idx-5] * 0.5:
            return Order(1, "波动缩小，平掉订单")


class TrendChangeC(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "趋势转变"
        self.describe = """当前趋势与5K前趋势不同，平掉订单"""
        self.tactic_type = TacticType.CLOSE

        self.factor_name = ['plus_di', 'minus_di']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        plus_di = self.bt_task.plus_di
        minus_di = self.bt_task.minus_di

        diff_multi = (plus_di[self.idx] - minus_di[self.idx]) * (plus_di[self.idx-5] - minus_di[self.idx-5])
        range_limit_cond = abs(plus_di[self.idx] - minus_di[self.idx]) > 10 and abs(plus_di[self.idx-5] - minus_di[self.idx-5]) > 10
        if diff_multi < 0 and range_limit_cond:  # 趋势相反，且-1，-6的趋势值绝对值均有一定数量，即大于10
            return Order(1, "趋势转变，平掉订单")


class TrendEnhanceC(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "趋势加强"
        self.describe = """当前趋势相对5K前趋势相当程度加强，平掉订单"""
        self.tactic_type = TacticType.CLOSE

        self.factor_name = ['plus_di', 'minus_di']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        plus_di = self.bt_task.plus_di
        minus_di = self.bt_task.minus_di

        diff_multi = (plus_di[self.idx] - minus_di[self.idx]) * (plus_di[self.idx-5] - minus_di[self.idx-5])
        range_limit_cond = abs(plus_di[self.idx-5] - minus_di[self.idx-5]) > 10
        trend_enhance_cond = abs((plus_di[self.idx] - minus_di[self.idx])) > abs((plus_di[self.idx-5] - minus_di[self.idx-5])) * 1.3
        if diff_multi > 0 and trend_enhance_cond and range_limit_cond:  # 趋势加强，且-6的趋势值绝对值有一定数量，
            return Order(1, "趋势加强，平掉订单")


class TrendWeakenedC(Tactic):
    def __init__(self):
        super().__init__()
        self.name = "趋势减弱"
        self.describe = """当前趋势相对5K前趋势相当程度减弱，平掉订单"""
        self.tactic_type = TacticType.CLOSE

        self.factor_name = ['plus_di', 'minus_di']  # 填入战法所用到的所有因子

    def execute(self) -> [OrderDir, str]:
        plus_di = self.bt_task.plus_di
        minus_di = self.bt_task.minus_di

        diff_multi = (plus_di[self.idx] - minus_di[self.idx]) * (plus_di[self.idx-5] - minus_di[self.idx-5])
        range_limit_cond = abs(plus_di[self.idx-5] - minus_di[self.idx-5]) > 10
        trend_weakened_cond = abs((plus_di[self.idx] - minus_di[self.idx])) < abs((plus_di[self.idx-5] - minus_di[self.idx-5])) * 0.7

        if diff_multi > 0 and trend_weakened_cond and range_limit_cond:  # 趋势减弱，且-6的趋势值绝对值有一定数量，即大于0.1 * minus_di[-6]
            return Order(1, "趋势减弱，平掉订单")










